﻿using System;
using System.Collections.Generic;

namespace _29._3_面向对象_泛型
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> arr = new List<int> { 8, 5, 6, 12, 1, 8, 36, 94, 1, 5, 4, 77, 22, 14, 58 };
            Console.WriteLine("Before : " + string.Join(" - ", arr));
            for (int i = 0; i < arr.Count - 1; i++)
            {
                for (int j = 0; j < arr.Count - i - 1; j++)
                {
                    int lhs = arr[j], rhs = arr[j + 1];
                    //SwapIfGreater(ref lhs, ref rhs);
                    if (lhs > rhs)
                    {
                        rhs += lhs;
                        // 3=6-3
                        // 3+2=5
                        lhs = rhs - lhs; // lhs+lhs = rhs 👉2lhs=rhs 👉lhs = rhs/2
                                                     // lhs = rhs / 2; //不成立
                        rhs -= lhs;
                    }
                    arr[j] = lhs;
                    arr[j + 1] = rhs;
                }
            }
            Console.WriteLine("After : " + string.Join(" - ", arr));
        }


        // Swap If Greater : 如果更大就交换
        // IComparable ： I ，interface ，Comparable 可对比的
        // temp :临时的 （变量）
        static void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
        {
            T temp;
            if (lhs.CompareTo(rhs) > 0)
            {
                temp = lhs;
                lhs = rhs;
                rhs = temp;
            }
        }
        //1.  int 如果更大就交换，不用临时变量
        //2. 自己研究 SwapIfGreater 怎么调用

        // 泛型方法可以重载,只要类型参数数量不一即可
        void DoWork() { }
        void DoWork<T>() { }
        void DoWork<T, U>() { }
    }

    // 泛型接口：
    interface ITest<T>
    {
    }
    interface ITest<T, V>
    {
    }
    interface ITest<T, U, V>
    {
    }

    //适用于类类型的接口规制同样适用于接口
    // 处理的元素一致，步伐一致, 泛型参数个数一致
    // interface Itesta<S,V> : ITest<S>  //ok
    //interface Itesta<S> : ITest<S,V>  // NG, 接口少声明了 V 
    interface Itesta<S, V> : ITest<S, V, V> //后面的接口需要三个参数，用前面出现的参数填充
    {
    }

    // 泛型接口的约束继承
    interface ITestbs<T> where T : struct
    {
    }

    // 一旦被继承的接口有约束，那么继承接口就必须（显式）补全这个约束
    interface ITestbbs<T> : ITestbs<T> where T : struct
    {
    }
    interface ITestbbsi<T> : ITestbs<T> where T : struct
    {
    }

    // 约束必须是  接口，非密封类，类型参数
    // 示例中， Book 结构，int32 不是有效的约束
    // 泛型中，想要约束类型为值类型，就只有一个选择：struct 
    //  这个规则不在乎你是 interface 还是 class
    //struct Book { }
    //interface ITestb<U> where U :Book
    //{
    //}
    //interface ITestint<U> where U : Int32
    //{ }
    //class Testint<U> where U : Int32
    //{ }

    interface ITestbp<T> where T : Program
    {
    }

    interface ITestbbp<T> : ITestbp<T> where T : Program
    {

    }

    interface ITestbc<T> where T : class
    {
    }

    interface ITestbbcp<T> : ITestbc<T> where T : Program
    {
    }

    interface ITestbbc<T> : ITestbc<T> where T : class
    {
    }
}
